import { emitter } from '@/utils/eventBus.ts'

class SoftPhone {
  constructor(config) {
    this.config = config
    // console.log(`config:${JSON.stringify(this.config)}`)
    this.websocket = undefined
    this.invokeid = 0
    this.session = null
    this.session2 = null
    this.connid = null
    this.isLogined = false
    this.isAutoReady = false
    this.autoReadySeconds = 3
    this.heartTimer = null

    this.onEventConnect = function () {}
    this.onEventStatus = function () {}
    this.onEventAgentLoginout = function () {}
    this.onEventGetAgentState = function () {}
    this.onEventAgentChaneSkill = function () {}
  }
  AgentSetBusy(busyCode) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentSetBusy'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    request.param.busyCode = busyCode

    this.doSend(JSON.stringify(request))
  }
  /*超管给坐席置忙*/
  SuperAgentBusy(data) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentSetBusy'
    request.param = new Object()
    request.param.agentId = data.agentId
    request.param.busyCode = data.busyCode
    this.doSend(JSON.stringify(request))
  }
  AgentSetIdle() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentSetIdle'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    this.doSend(JSON.stringify(request))
  }
  /*超管给坐席置闲*/
  SuperAgentSetIdle(data) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentSetIdle'
    request.param = new Object()
    request.param.agentId = data.agentId
    this.doSend(JSON.stringify(request))
  }
  AgentLogin() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentLogin'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    request.param.password = this.config.password
    request.param.device = this.config.extensionNum
    request.param.isLogined = this.isLogined
    request.param.connid = this.connid
    if (this.config.skills) {
      request.param.skills = this.config.skills
    }
    // request.param.skills = [
    //   {
    //     skill_id:1000,
    //     skill_level:2,
    //     queue_type:1
    //   },
    //   {
    //     skill_id:1002,
    //     skill_level:2,
    //     queue_type:1
    //   },
    //   {
    //     skill_id:1003,
    //     skill_level:2,
    //     queue_type:1
    //   }
    // ];

    this.doSend(JSON.stringify(request))
  }

  AgentLoginOut(callback) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentLoginout'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    request.param.connid = this.connid

    this.doSend(JSON.stringify(request))

    if (callback) this.onEventAgentLoginout = callback
  }
  /*超管签出*/
  SuperAgentLoginOut(data) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentLoginout'
    request.param = new Object()
    request.param.agentId = data.agentId
    request.param.password = data.password

    this.doSend(JSON.stringify(request))
  }

  AgentGetState(callback) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentGetState'
    request.param = new Object()
    request.param.agentId = this.config.agentId

    this.doSend(JSON.stringify(request))

    if (callback) this.onEventGetAgentState = callback
  }
  /*超管监听*/
  SuperAgentGetState(callback, agentId) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentGetState'
    request.param = new Object()
    request.param.agentId = agentId

    this.doSend(JSON.stringify(request))

    if (callback) this.onEventGetAgentState = callback
  }
  doAgentChangeSkill(callback) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentChangeSkill'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    request.param.skills = [
      {
        skill_id: 1000,
        skill_level: 2,
        queue_type: 1
      },
      {
        skill_id: 1002,
        skill_level: 2,
        queue_type: 1
      },
      {
        skill_id: 1003,
        skill_level: 2,
        queue_type: 1
      }
    ]

    this.doSend(JSON.stringify(request))

    if (callback) this.onEventAgentChaneSkill = callback
  }

  writeLog(message) {
    // console.log(`[SoftPhone]:${message}`)
  }

  StartConnect(callback) {
    let that = this
    if (this.websocket != undefined) {
      delete this.websocket
    }
    this.websocket = new WebSocket(this.config.address)
    this.websocket.onopen = function (evt) {
      that.onOpen(evt)
    }
    this.websocket.onclose = function (evt) {
      that.onClose(evt)
    }
    this.websocket.onmessage = function (evt) {
      that.onMessage(evt)
    }
    this.websocket.onerror = function (evt) {
      that.onError(evt)
    }

    if (callback) this.onEventConnect = callback
  }

  DisConnect() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'DisConnect'
    this.doSend(JSON.stringify(request))
    this.websocket.close()
  }

  MakeCall(dialNumber) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentMakeCall'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    request.param.caller = this.config.extensionNum
    request.param.called = dialNumber
    this.doSend(JSON.stringify(request))
  }

  ClearCall() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'ClearCall'
    request.param = new Object()
    request.param.connection = this.session
    this.doSend(JSON.stringify(request))
  }

  AnswerCall() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AnswerCall'
    request.param = new Object()
    request.param.connection = this.session
    this.doSend(JSON.stringify(request))
  }

  HoldCall() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'HoldCall'
    request.param = new Object()
    request.param.connection = this.session
    request.param.activeCall = this.session2
    this.doSend(JSON.stringify(request))
  }

  RetrieveCall() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'RetrieveCall'
    request.param = new Object()
    request.param.connection = this.session
    this.doSend(JSON.stringify(request))
  }
  // 拦截
  InterceptCall(dialNumber) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'InterceptCall'
    request.param = new Object()
    request.param.connection = this.session
    request.param.called = dialNumber
    this.doSend(JSON.stringify(request))
  }
  // 单步转接
  SingleStepTransferCall(dialNumber) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'SingleStepTransferCall'
    request.param = new Object()
    request.param.connection = this.session
    request.param.connection2 = this.session2
    request.param.called = dialNumber
    this.doSend(JSON.stringify(request))
  }
  // 咨询
  ConsultationCall(dialNumber) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'ConsultationCall'
    request.param = new Object()
    request.param.connection = this.session
    request.param.connection2 = this.session2
    request.param.called = dialNumber
    request.param.device = this.config.extensionNum
    this.doSend(JSON.stringify(request))
  }
  // 咨询转接
  ConsultationTransfer() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'TransferCall'
    request.param = new Object()
    request.param.activeCall = this.session2
    request.param.connection = this.session
    this.doSend(JSON.stringify(request))
  }
  // 取消咨询
  ReconnectCall() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'ReconnectCall'
    request.param = new Object()
    request.param.activeCall = this.session2
    request.param.connection = this.session
    this.doSend(JSON.stringify(request))
  }

  // 咨询三方
  ThreeWay() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'ThreeWay'
    request.param = new Object()
    request.param.activeCall = this.session2
    request.param.connection = this.session
    this.doSend(JSON.stringify(request))
  }
  // 监听
  ListenIn(agentId, monitorType) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentListenIn'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    request.param.monitorType = monitorType
    request.param.monitoringScope = 'Agent'
    request.param.targetDevice = agentId
    request.param.device = this.config.extensionNum
    this.doSend(JSON.stringify(request))
  }
  /*超管监听*/
  SuperListenIn(agentId, monitorType, data) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentListenIn'
    request.param = new Object()
    request.param.agentId = data.agentId
    request.param.monitorType = monitorType
    request.param.monitoringScope = 'Agent'
    request.param.targetDevice = agentId
    request.param.device = data.extensionNum
    this.doSend(JSON.stringify(request))
  }
  // 强插
  BargeIn() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentBargeIn'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    request.param.device = this.config.extensionNum
    this.doSend(JSON.stringify(request))
  }
  /*超管强插*/
  SuperBargeIn(data) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentBargeIn'
    request.param = new Object()
    request.param.agentId = data.agentId
    request.param.device = data.extensionNum
    this.doSend(JSON.stringify(request))
  }
  // 拦截
  InterceptIn() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentInterceptIn'
    request.param = new Object()
    request.param.agentId = this.config.agentId
    this.doSend(JSON.stringify(request))
  }
  /*超管 拦截*/
  SuperInterceptIn(data) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'AgentInterceptIn'
    request.param = new Object()
    request.param.agentId = data.agentId
    this.doSend(JSON.stringify(request))
  }
  // 转接满意度
  Transfer2Satisfy() {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'Transfer2Satisfy'
    request.param = new Object()
    request.param.connection = this.session
    this.doSend(JSON.stringify(request))
  }

  // 转接技能id
  Transfer2Skill(skill_id) {
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'Transfer2Skill'
    request.param = new Object()
    request.param.connection = this.session
    request.param.skill_id = skill_id
    this.doSend(JSON.stringify(request))
  }

  onOpen(evt) {
    this.writeLog('websocket已连接')
    let request = new Object()
    request.invokeID = this.invokeid++
    request.type = 'request'
    request.request = 'Connect'
    request.param = new Object()
    request.param.LoginID = this.config.agentId
    request.param.passWord = this.config.password
    request.param.version = '1.0.0.0'
    request.param.type = 1
    this.doSend(JSON.stringify(request))
  }

  onClose(evt) {
    this.writeLog('websocket已断开连接')
    if (this.heartTimer) {
      clearInterval(this.heartTimer)
      this.heartTimer = null
    }
    if (this.isLogined) {
      ElMessage.warning('坐席已断开连接 重新登录')
      // this.writeLog('websocket已断开连接 重新登录')
      this.StartConnect((data) => {
        this.AgentLogin()
      })
    }
  }

  onMessage(evt) {
    // this.writeLog(`Receive: ${evt.data}`)
    console.info(`Receive: ${evt.data}`)
    let event = JSON.parse(evt.data)
    console.log(event)
    if (event.response === 'HeartBeat') {
      return
    }
    if (event.event === 'ConnectionCleared') {
      emitter.emit('updateDuration', event.param.callid)
      if (this.session != null && this.session.sessionID == event.param.connection.sessionID) {
        this.session = this.session2
        this.session2 = null
      }
      if (this.session2 != null && this.session2.sessionID == event.param.connection.sessionID) {
        this.session2 = null
      }
    } else if (event.event === 'CallCleared') {
      this.session = null
      this.session2 = null
    } else if (
      event.event === 'Delivered' ||
      event.event === 'Received' ||
      event.event === 'Originated'
    ) {
      if (this.session == null) this.session = event.param.connection
      else this.session2 = event.param.connection
    } else if (event.response === 'MergeCall') {
      if (this.session != null) this.session.callID = event.param.newConnection.callID
      if (this.session2 != null) this.session2.callID = event.param.newConnection.callID
    } else if (event.response == 'TransferService' && event.status == 0) {
      this.session = null
    } else if (event.response == 'Connect') {
      this.connid = event.param.connid
      this.onEventConnect(event)
    } else {
      if (event.type == 'event') {
        if (event.event == 'AgentLoginout') {
          this.onEventAgentLoginout(event)
        }
        if (event.event === 'AgentCallCallCleared') {
          this.session = null
          this.session2 = null
          //播放挂断的音频
          document.getElementById('outone')?.play()
          if (this.isAutoReady) {
            if (this.autoReadySeconds <= 0) {
              this.AgentSetIdle()
            } else {
              setTimeout(() => {
                this.AgentSetIdle()
              }, this.autoReadySeconds * 1000)
            }
          } else {
            this.AgentSetBusy('Busy')
          }
        } else if (event.event === 'AgentCallInAlerting') {
          this.session = event.param.connection //被叫
          this.session2 = event.param.connection2 //主叫
        }

        if (event.event.startsWith('Agent')) {
          this.onEventStatus(event)
        }
      } else {
        if (event.response == 'AgentGetState') {
          this.onEventGetAgentState(event.param.agents)
        } else if (event.response == 'AgentChaneSkill') {
          this.onEventAgentChaneSkill(event.param)
        } else {
          this.onEventStatus(event)
        }
      }
    }
  }

  onError(evt) {
    this.writeLog(`ERROR:${evt.data}`)
    this.writeLog(`已断开连接`)
  }

  doSend(message) {
    // console.log('message', message)
    if (this.websocket.readyState == 1) {
      this.websocket.send(message)
      this.writeLog(`SENT:${message}`)
    } else {
      this.writeLog(message)
    }
  }

  startHeartBeatTimer() {
    let _this = this
    if (_this.heartTimer) {
      clearInterval(_this.heartTimer)
      _this.heartTimer = null
    }

    _this.heartTimer = setInterval(() => {
      var request = new Object()
      request.invokeID = _this.invokeid++
      request.type = 'request'
      request.request = 'HeartBeat'
      request.param = new Object()
      request.param.connid = _this.connid
      request.param.agentId = _this.config.agentId
      request.param.extensionNum = _this.config.extensionNum
      request.param.userdata = '中文编码'
      request.param.correlatorData = {}

      _this.doSend(JSON.stringify(request))
    }, 3e3)
  }

  setAutoReady(v) {
    this.isAutoReady = v
  }

  setAutoReadySeconds(seconds) {
    this.autoReadySeconds = seconds
  }
}
export default SoftPhone
